import { Component, OnInit } from '@angular/core';
import * as d3 from 'd3';

@Component({
  selector: 'app-main-map',
  templateUrl: './main-map.component.html',
  styleUrls: ['./main-map.component.less'],
})
export class MainMapComponent implements OnInit {
  mapJson = require('src/assets/full-page/chengdu.json');
  svg: any;
  zoom: any;
  allowZoom = true; // 允许缩放
  tooltip: any;
  constructor() {}
  ngOnInit(): void {
    this.drawMap();
  }
  // /**
  //  * 获取成都goeJson文件
  //  */
  // getChengDuGoeJson() { }

  /**
   * d3+svg画地图
   */
  drawMap(): void {
    const mapJson = this.mapJson; // 成都市goeJson数据对象
    const width = 600; // svg容器宽度
    const height = 600; // svg容器高度
    const padding = 10; // 地图svg内边距
    const mapColor = '#114a93'; // 地图区块底色
    const mapLineColor = '#0d67c7'; // 边线颜色
    const bgmapColor = '#00008b'; // 底部阴影地图区块底色
    const bgmapLineColor = '#0d67c7'; // 底部阴影边线颜色
    const x0 = padding; // 地图起点横坐标
    const y0 = padding; // 地图起点纵坐标
    const x1 = width - padding * 2; // 地图终点横坐标
    const y1 = height - padding * 2; // 地图终点纵坐标

    // 新建svg图形画布
    const svg = d3.select('#mainMap').append('svg').attr('width', width).attr('height', height);
    // 提示信息
    this.tooltip = d3
      .select('#mainMap')
      .append('div')
      .attr('opacity', 0)
      .style('position', 'absolute')
      .style('color', 'white')
      .style('font', '12px sans-serif')
      .style('border-radius', '8px')
      .style('pointer-events', 'none')
      .style('background', '#333333')
      .style('padding', '6px 10px');

    // 画地图
    // 1.定义投影和生成器
    const projection: any = d3.geoMercator().fitExtent(
      [
        [x0, y0],
        [x1, y1],
      ],
      mapJson,
    ); // 把地图绘制在给定画布的中心
    // .center([103.946, 30.666])       // 地图中心位置,成都：104.06327247619629是经度,30.662482212884644是纬度
    // .scale(scale)             // 设置缩放量 18000
    // .translate([width / 2, height / 2]);      // 设置平移量

    // 定义地理路径生成器,使每一个坐标都会先调用此投影,才产生路径值
    const mapPath: any = d3.geoPath().projection(projection); // 设定投影

    const chengdu = mapJson.features; // 成都地图goeJson.features数据
    const bgmap = svg.append('g'); // 地图底部阴影
    const groups = svg.append('g'); // 省市边界
    const cityPoint = svg.append('g'); // 城市圆点
    const cityLabel = svg.append('g'); // 城市名称标签

    // 2.画地图
    // 添加城市标签
    cityLabel
      .selectAll('label')
      .data(chengdu) // 绑定数据
      .enter()
      .append('text')
      .text((d: any) => {
        return d.properties.name;
      })
      .attr('x', (d: any) => {
        return projection(d.properties.center)[0];
      })
      .attr('y', (d: any) => {
        return projection(d.properties.center)[1] - 5;
      })
      .attr('text-anchor', 'middle' /* 文本水平居中 */)
      .attr('dominant-baseline', 'middle' /* 文本垂直居中 */)
      .attr('fill', 'white')
      .attr('font-size', 10)
      .style('transform', (d, i) => {
        if (i === 0) {
          // 锦江区单独设置样式
          return `translate(${10}px, ${18}px)`;
        }
        if (i === 1) {
          // 青羊区单独设置样式
          return `translate(${-30}px, ${2}px)`;
        }
        // if (i === 2) {    // 金牛区单独设置样式
        //   return `translate(${0}px, ${0}px)`;
        // }
        if (i === 3) {
          // 武侯区单独设置样式
          return `translate(${-10}px, ${14}px)`;
        }
        if (i === 4) {
          // 成华区单独设置样式
          return `translate(${10}px, ${-2}px)`;
        }
        if (i === 6) {
          // 青白江区单独设置样式
          return `translate(${6}px, ${12}px)`;
        }
        return 'null';
      });

    // 添加城市圆点
    cityPoint
      .selectAll('circle')
      .data(this.mapJson.features) // 绑定数据
      .enter()
      .append('circle')
      .attr('class', 'point')
      .attr('cx', (d: any) => {
        return projection(d.properties.center)[0];
      })
      .attr('cy', (d: any) => {
        return projection(d.properties.center)[1];
      })
      .attr('stroke', 'red')
      .attr('stroke-width', 1)
      .attr('r', 1);

    // 添加城市边界
    groups
      .selectAll('path')
      .data(chengdu) // 绑定数据
      .enter()
      .append('svg:path')
      .style('fill', mapColor)
      .attr('stroke', mapLineColor)
      .attr('d', mapPath)
      .on('mouseover', (e: any, d: any) => {
        // 鼠标滑过变色
        d3.select(e.path[0]).style('fill', 'steelblue');
        // 设置tooltip文字
        this.tooltip
          .html(d.properties.name + '销售额为' + '<br/>' + d.properties.name + '百万台')
          // 设置tooltip的位置(left,top 相对于页面的距离)
          .style('left', e.offsetX + 'px')
          .style('top', e.offsetY + 20 + 'px')
          .style('opacity', 1.0);
      })
      .on('mouseout', (e: any) => {
        d3.select(e.path[0]).style('fill', mapColor);
        this.tooltip.style('opacity', 0);
      });

    // 画地图底部阴影
    bgmap
      .selectAll('path')
      .data(chengdu) // 绑定数据
      .enter()
      .append('svg:path')
      .style('fill', bgmapColor)
      .attr('stroke', bgmapLineColor)
      .attr('d', mapPath)
      .attr('transform', 'translate(10,10)');

    /**
     * 拖动及缩放
     */
    this.zoom = d3.zoom();
    this.svg = svg;
    this.initSvg();
  }

  /**
   * 处理svg初始化位置及放大缩小范围约定
   */
  initSvg(): any {
    // 设置初始比例，并注入函数
    this.svg.call(
      this.zoom
        .scaleExtent([1 / 4, 8]) // 缩放比例
        .on('start', this.zoomeStart)
        .on('zoom', this.allowZoom ? this.zoomed : null)
        .on('end', this.zoomeEnd),
    );
  }

  /**
   * 定位并且放大缩小函数 相似功能使用函数处理
   */
  zoomed(e: any): void {
    const dg = d3.selectAll('g');
    const transform = e.transform;
    dg.attr('transform', 'translate(' + transform.x + ',' + transform.y + ') scale(' + transform.k + ')');
  }

  /**
   * 移动前处理
   */
  zoomeStart(): void {}

  /**
   * 移动后处理
   */
  zoomeEnd(): void {}
}
